package com.google.jessewilson.codesearch.ui;

import javax.swing.table.TableModel;
import javax.swing.*;

/**
 * Receive callbacks when tablecells are rendered.
 *
 * TODO(jessewilson): clean this up, I don't like how it has to
 *    replace the table's model
 *
 * @author jessewilson
 */
public interface TableAccessListener {
  void cellLoaded(int row, int column, Object value, TableModel source);

  class Support {
    public static void install(TableAccessListener listener, JTable table) {
      table.setModel(new MonitoringTableModel(table.getModel(), listener));
    }

    public static void uninstall(TableAccessListener listener, JTable table) {
      TableModel tableModel = table.getModel();
      if (tableModel instanceof MonitoringTableModel
          && ((MonitoringTableModel)tableModel).listener == listener) {
        table.setModel(((MonitoringTableModel)tableModel).delegate);
      } else {
        throw new UnsupportedOperationException("TableAccessListener cannot uninstall deep listeners!");
      }
    }

    private static class MonitoringTableModel extends TableModelDecorator {
      private final TableAccessListener listener;

      public MonitoringTableModel(TableModel delegate, TableAccessListener listener) {
        super(delegate);
        this.listener = listener;
      }

      public Object getValueAt(int rowIndex, int columnIndex) {
        Object value = super.getValueAt(rowIndex, columnIndex);
        listener.cellLoaded(rowIndex, columnIndex, value, delegate);
        return value;
      }
    }
  }
}
